Escrow contract switch#554
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (4)
📝 WalkthroughWalkthroughAdds legacy escrow contract selection on the escrow page, routes reads and withdrawals through a selectable escrow address, disables deposit and authorization actions in legacy mode, and shows a dismissible homepage banner when the legacy address is configured. ChangesLegacy Escrow Contract Selector
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Tools execution failed with the following error: Failed to run tools: 13 INTERNAL: Received RST_STREAM with code 2 (Internal server error) Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
/run-security-scan |
alexcos20
left a comment
There was a problem hiding this comment.
AI automated code review (Gemini 3).
Overall risk: low
Summary:
This PR is exceptionally well-implemented. It handles the legacy escrow contract redeployment seamlessly by adding a fallback selector and safe read-only/withdraw modes. The approach used to handle React race conditions during data fetching is highly commendable. All edge cases regarding disabled deposits and authorizations on the legacy contract have been thoroughly accounted for.
Comments:
• [INFO][bug] It is a good practice to wrap localStorage access in a try...catch block. In some environments (like Safari Private Browsing or restricted iframes), accessing localStorage throws a SecurityError or QuotaExceededError, which could cause the React component to crash during mount or user interaction.
Consider wrapping the logic safely:
- setVisible(localStorage.getItem(DISMISSED_KEY) !== 'true');
+ try {
+ setVisible(localStorage.getItem(DISMISSED_KEY) !== 'true');
+ } catch (err) {
+ setVisible(true);
+ }And in your dismiss handler:
- localStorage.setItem(DISMISSED_KEY, 'true');
- setVisible(false);
+ try {
+ localStorage.setItem(DISMISSED_KEY, 'true');
+ } catch (err) {
+ // ignore
+ }
+ setVisible(false);• [INFO][style] The way you handled race conditions with loadIdRef and escrowAddressRef is excellent! Ensuring that late-arriving data from an old contract fetch doesn't overwrite the current state is a very robust pattern for data fetching in React.
• [INFO][other] Great job on preventing deposits to the legacy contract right at the UI level while keeping the hook usage clean.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/components/escrow/escrow-token-panel.tsx (1)
220-254: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winWithdraw/deposit form values persist across contract switch.
EscrowTokenPanelisn't remounted whenescrowAddresschanges (no key change), and there's no effect resettingdepositForm/withdrawFormon that change. A previously-entered amount from the current contract's view carries over when switching to the legacy view (or back), which can confuse users even though submission still correctly targets the resolvedescrowAddress.💡 Proposed fix: reset forms when escrowAddress changes
const EscrowTokenPanel = ({ token, spenders, loadingSpenders, onChange, escrowAddress }: EscrowTokenPanelProps) => { const [isCreateOpen, setIsCreateOpen] = useState(false); const isLegacy = !!escrowAddress; + + useEffect(() => { + depositForm.resetForm(); + withdrawForm.resetForm(); + }, [escrowAddress]);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/escrow/escrow-token-panel.tsx` around lines 220 - 254, The deposit and withdraw amounts in EscrowTokenPanel are persisting when escrowAddress changes because the component is reused and the Formik state is never reset. Add an effect in EscrowTokenPanel that watches escrowAddress and calls both depositForm.resetForm() and withdrawForm.resetForm() whenever the contract view switches, so the amount fields clear when moving between legacy and current escrow views.
🧹 Nitpick comments (2)
src/components/homepage/legacy-escrow-banner.module.css (1)
8-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffMagic-number coupling to
hero-section.module.cssbreakpoints.The negative
margin-topvalues and breakpoints are hand-copied to mirror another file's layout, per the comment. Any future change to hero padding/breakpoints silently desyncs this file since there's no shared constant/variable enforcing the relationship.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/homepage/legacy-escrow-banner.module.css` around lines 8 - 24, The banner spacing in the legacy escrow CSS is hard-coupled to hero-section layout values via copied breakpoints and negative margins. Refactor the .banner rules to use shared design tokens or CSS custom properties sourced from the hero layout, and update the `@media` thresholds to reference the same centralized values so both files stay in sync. Use the existing .banner selector and the hero-section.module.css breakpoint/padding definitions as the single source of truth.src/components/homepage/legacy-escrow-banner.tsx (1)
20-31: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueGuard localStorage access against exceptions.
localStorage.getItem/setItemare called unguarded. In restrictive environments (e.g., private browsing modes, storage disabled by policy), these calls can throw and crash the component since there's no error boundary/try-catch here.🛡️ Proposed defensive fix
useEffect(() => { - setVisible(localStorage.getItem(DISMISSED_KEY) !== 'true'); + try { + setVisible(localStorage.getItem(DISMISSED_KEY) !== 'true'); + } catch { + setVisible(true); + } }, []); const dismiss = () => { - localStorage.setItem(DISMISSED_KEY, 'true'); - setVisible(false); + try { + localStorage.setItem(DISMISSED_KEY, 'true'); + } catch { + // ignore storage errors; still hide for this session + } + setVisible(false); };🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/homepage/legacy-escrow-banner.tsx` around lines 20 - 31, The localStorage calls in LegacyEscrowBanner are unguarded and can throw in restricted environments. Update the useEffect initializer and the dismiss handler to wrap localStorage.getItem and localStorage.setItem in defensive try/catch logic, and fall back to a safe default if storage is unavailable. Keep the fix localized to LegacyEscrowBanner and its dismiss function so the component still renders without crashing when storage access fails.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@src/components/escrow/escrow-token-panel.tsx`:
- Around line 220-254: The deposit and withdraw amounts in EscrowTokenPanel are
persisting when escrowAddress changes because the component is reused and the
Formik state is never reset. Add an effect in EscrowTokenPanel that watches
escrowAddress and calls both depositForm.resetForm() and
withdrawForm.resetForm() whenever the contract view switches, so the amount
fields clear when moving between legacy and current escrow views.
---
Nitpick comments:
In `@src/components/homepage/legacy-escrow-banner.module.css`:
- Around line 8-24: The banner spacing in the legacy escrow CSS is hard-coupled
to hero-section layout values via copied breakpoints and negative margins.
Refactor the .banner rules to use shared design tokens or CSS custom properties
sourced from the hero layout, and update the `@media` thresholds to reference the
same centralized values so both files stay in sync. Use the existing .banner
selector and the hero-section.module.css breakpoint/padding definitions as the
single source of truth.
In `@src/components/homepage/legacy-escrow-banner.tsx`:
- Around line 20-31: The localStorage calls in LegacyEscrowBanner are unguarded
and can throw in restricted environments. Update the useEffect initializer and
the dismiss handler to wrap localStorage.getItem and localStorage.setItem in
defensive try/catch logic, and fall back to a safe default if storage is
unavailable. Keep the fix localized to LegacyEscrowBanner and its dismiss
function so the component still renders without crashing when storage access
fails.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 729b9975-ff6d-4e15-b507-9bbf9e81ae74
📒 Files selected for processing (12)
README.mdsrc/components/escrow/escrow-page.module.csssrc/components/escrow/escrow-page.tsxsrc/components/escrow/escrow-token-panel.module.csssrc/components/escrow/escrow-token-panel.tsxsrc/components/homepage/hero-section.tsxsrc/components/homepage/legacy-escrow-banner.module.csssrc/components/homepage/legacy-escrow-banner.tsxsrc/constants/escrow.tssrc/lib/ocean-provider.tssrc/lib/use-escrow-data.tssrc/lib/use-withdraw-tokens.ts
There was a problem hiding this comment.
🧹 Nitpick comments (2)
src/components/homepage/hero-section.module.css (2)
72-84: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMagic numbers duplicate hero's nav-overlap geometry.
-80px/-90px/-120pxmirror.root's--nav-overlapand its own breakpoint overrides but aren't derived from them. If the hero's overlap or padding changes, these values will silently drift out of sync.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/homepage/hero-section.module.css` around lines 72 - 84, The .legacyEscrowBanner spacing is hard-coded with magic numbers that duplicate the hero nav-overlap values and can drift from .root. Update the hero-section.module.css rules for .legacyEscrowBanner to derive its negative margin from the same --nav-overlap geometry used by .root, preferably via a shared CSS variable or calc() expression across the matching media breakpoints, so the banner stays in sync if the hero overlap changes.
72-86: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReuse the hero overlap offset here
Themargin-topvalues here duplicate the hero’s breakpoint-specific nav overlap. Pull this from the same custom property or shared rule so the banner stays aligned if the hero spacing changes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/components/homepage/hero-section.module.css` around lines 72 - 86, The .legacyEscrowBanner margin-top values are duplicating the hero’s breakpoint-specific overlap spacing, so update this rule to reuse the same shared custom property or overlapping spacing source used by the hero section. Keep the existing breakpoint behavior in sync by referencing the shared hero offset in hero-section.module.css rather than hardcoding separate values here.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/components/homepage/hero-section.module.css`:
- Around line 72-84: The .legacyEscrowBanner spacing is hard-coded with magic
numbers that duplicate the hero nav-overlap values and can drift from .root.
Update the hero-section.module.css rules for .legacyEscrowBanner to derive its
negative margin from the same --nav-overlap geometry used by .root, preferably
via a shared CSS variable or calc() expression across the matching media
breakpoints, so the banner stays in sync if the hero overlap changes.
- Around line 72-86: The .legacyEscrowBanner margin-top values are duplicating
the hero’s breakpoint-specific overlap spacing, so update this rule to reuse the
same shared custom property or overlapping spacing source used by the hero
section. Keep the existing breakpoint behavior in sync by referencing the shared
hero offset in hero-section.module.css rather than hardcoding separate values
here.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 8dc91422-bd2e-461c-81bb-9d23276cb680
📒 Files selected for processing (5)
src/components/escrow/escrow-page.tsxsrc/components/homepage/hero-section.module.csssrc/components/homepage/hero-section.tsxsrc/components/homepage/legacy-escrow-banner.module.csssrc/components/homepage/legacy-escrow-banner.tsx
✅ Files skipped from review due to trivial changes (1)
- src/components/homepage/legacy-escrow-banner.module.css
🚧 Files skipped from review as they are similar to previous changes (3)
- src/components/homepage/hero-section.tsx
- src/components/escrow/escrow-page.tsx
- src/components/homepage/legacy-escrow-banner.tsx

Fixes #552 .
Changes proposed in this PR:
Summary by CodeRabbit
NEXT_PUBLIC_LEGACY_ESCROW_ADDRESSenvironment variable.